package booking.utils;

import java.util.HashMap;

public class Snake {

	private int rowCount = 4;

	public Snake() {
		init();
	}

	/**
	 * 方向 0.右,1.下,2.左,3.上
	 */
	int direction = 0;

	/**
	 * 保存占据格子的map String 坐标 如: 1-1,3-1 int 当前数字
	 */
	HashMap<String, Integer> map = new HashMap<>();

	public void init() {
		Position position = new Position(1, 1);
		System.out.println(position.toLocation() + " " + 1);
		addNumber(position, 1);
		// position = excute(position);
		for (int i = 2; i <= rowCount * rowCount; i++) {
			System.out.println(" ");
			System.out.println(position.toLocation() + " old postion " + direction);
			position = excute(position);
			System.out.println(position.toLocation() + " " + i + " direction: " + direction);
			addNumber(position, i);
		}

		for (int j = 1; j <= rowCount; j++) {
			for (int i = 1; i <= rowCount; i++) {
				String location = j + "-" + i;
				System.out.print("[" + map.get(location) + "]" + "\t");
			}
			System.out.println();
		}

	}

	/**
	 * 保存坐标
	 * 
	 * @param position
	 * @param number
	 */
	public void addNumber(Position position, int number) {
		String location = position.toLocation();
		map.put(location, number);
	}

	/**
	 * 当前postion 知否被占据
	 * 
	 * @param position
	 * @return
	 */
	public boolean haveItem(Position position) {
		String location = position.toLocation();
		boolean flag = map.get(location) != null;
		// System.out.println("have item " + flag);
		return flag;
	}

	/**
	 * 该position是否超出边界
	 * 
	 * @param position
	 * @return
	 */
	public boolean isOutofBound(Position position) {

		System.out.println("bound " + position.toLocation());
		boolean flag = position.getRow() > rowCount || position.getColumn() > rowCount;
		if (flag) {
			return true;
		}
		if (position.getRow() < 1) {
			return true;
		}
		if (position.getColumn() < 1) {
			return true;
		}
		// boolean flag2 = position.getRow() <= 1 || position.getColumn() <= 1;
		// if (flag2) {
		// return true;
		// }
		// System.out.println("isOutofBound " + flag);
		return false;
	}

	/**
	 * 这一格是否满足条件
	 * 
	 * @param position
	 * @return
	 */
	public boolean isAvailable(Position position) {
		if (haveItem(position) || isOutofBound(position)) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 返回要占据的下一格
	 * 
	 * @param position
	 * @return
	 */

	public Position excute(Position position) {
		Position nextPostion = position;
		switch (direction) {
		case 0:
			// 向右
			nextPostion = position.goRigth();
			break;
		case 1:
			// 向下
			nextPostion = nextPostion.goDown();
			break;
		case 2:
			// 向左
			nextPostion = nextPostion.goLeft();
			break;
		case 3:
			// 向上
			nextPostion = nextPostion.goUp();
			break;
		default:
			break;
		}
		if (isAvailable(nextPostion)) {
			return nextPostion;
		} else {
			toNextDirection();
			return excute(position);
		}
	}

	public void toNextDirection() {
		System.out.println("old direction " + direction);
		direction = (direction + 1) % 4;
		System.out.println("new direction " + direction);
	}

	public static void main(String[] args) {
		new Snake();
	}
}

class Position {

	public String toLocation() {
		return row + "-" + column;
	}

	public Position goLeft() {
		System.out.println("goLeft");
		return new Position(row, column - 1);
	}

	public Position goRigth() {
		System.out.println("goRigth");
		return new Position(row, column + 1);
	}

	public Position goUp() {
		System.out.println("goUp");
		return new Position(row - 1, column);
	}

	public Position goDown() {
		System.out.println("goDown");
		return new Position(row + 1, column);
	}

	public Position(int row, int column) {
		this.row = row;
		this.column = column;
	}

	private int column;
	private int row;

	public int getColumn() {
		return column;
	}

	public void setColumn(int column) {
		this.column = column;
	}

	public int getRow() {
		return row;
	}

	public void setRow(int row) {
		this.row = row;
	}
}
